package dq.study.shiro.test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.permission.PermissionResolver;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;

/**
 * @author dongqun
 * @date 2020/4/10 10:18
 */
public class AuthService {

    public Subject login(String path, String username, String password) {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:" + path);
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(username, password));
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }
//        PrincipalCollection collection = subject.getPrincipals();
//        System.out.println(collection.asList());
//        Assert.assertTrue(subject.isAuthenticated());
        return subject;
    }

    @Test
    public void testHasRole() {
        login("shiro-role.ini","zhangsan", "123");
        Subject subject = SecurityUtils.getSubject();
        Assert.assertTrue(subject.hasRole("role1"));
        Assert.assertTrue(subject.hasRole("role2"));
//        Assert.assertTrue(subject.hasRole("role3"));
        Assert.assertTrue(subject.hasAllRoles(Arrays.asList("role1","role2")));
        boolean[] result = subject.hasRoles(Arrays.asList("role1","role2","role3"));
        Assert.assertTrue(result[0]);
        Assert.assertTrue(result[1]);
        Assert.assertTrue(result[2]);
    }
    @Test
    public void testCheckRole(){
        login("shiro-role.ini","zhangsan", "123");
        Subject subject = SecurityUtils.getSubject();
        subject.checkRole("role1");
    }

    @Test(expected = UnauthorizedException.class)
    public void testPermission(){
        login("shiro-permission.ini","zhangsan", "123");
        Subject subject = SecurityUtils.getSubject();
        Assert.assertTrue(subject.isPermitted("user:create"));
        Assert.assertTrue(subject.isPermitted("user:create","user:update")[0]);
        Assert.assertTrue(subject.isPermitted(new WildcardPermission("user:create")));
        subject.checkPermission("user:delete");
    }

    @Test
    public void testWilcardPermission(){
        login("shiro-permission.ini","zhangsan", "123");
        Subject subject = SecurityUtils.getSubject();
        subject.checkPermission("system:user:dddd");
    }

    @RequiresPermissions("auth:permit:test")
    public String testPermit(){
        return "你拥有了打开迷宫带门的瑶池";
    }


    public static void main(String[] args) {
        AuthService authService = new AuthService();
        Subject subject = authService.login("shiro-authentication.ini","zhangsan", "123");
        System.out.println(subject.isAuthenticated());
//        subject.checkPermission("system:user:add");
//        subject.checkPermission("system:user:add");
//        subject.checkPermission("system:user:add");
//        subject.checkPermission("system:user:add");
//        if (subject.isPermitted("system:user:asdasda")){
//            System.out.println(authService.testPermit());
//        }
    }
}
